using System.Text;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Autofac.Extras.DynamicProxy;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using xjjxmm.infrastructure.Authorizations;
using xjjxmm.infrastructure.Common;
using xjjxmm.infrastructure.compont;
using xjjxmm.infrastructure.Middleware;
using xjjxmm.infrastructure.xjjxmmLog.LogKit;
using XjjXmm.Infrastructure.Configuration;
using XjjXmm.Infrastructure.Constant;
using XjjXmm.Infrastructure.Ioc;
using XjjXmm.Infrastructure.Jwt;
using XjjXmm.Infrastructure.ToolKit;

namespace xjjxmm.infrastructure.SetUp
{
    public static class StartUp
    {
        private static List<ICompont?>? componts = null;
        private static List<ICompont?> GetComponts()
        {
            if (componts == null)
            {
                var frameConfig = ConfigHelper.GetSection<FrameworkConfig>(CommonConstant.FrameworkConfigKey);

                componts = new List<ICompont?>();
                var tmpComponts = ReflectKit.SearchTypeAndCreate<ICompont>().ToList();
                if(frameConfig!.Componts != null)
                {
                    foreach(var compont in tmpComponts)
                    {
                        var com = frameConfig!.Componts.Where(t=>t.Name == compont?.GetType().Name).FirstOrDefault();
                        if(com == null)
                        {
                            componts.Add(compont);
                        }
                        else if(com.Enabled == null || com.Enabled == true)
                        {
                            if(com.Order != null && compont != null)
                            {
                                compont.Order = com.Order.Value;
                            }
                            componts.Add(compont);
                        }
                    }
                    
                }
                else
                {
                    componts = tmpComponts;
                }

                componts = componts
                    .OrderBy(t => t?.Order)
                    .ToList();

               
            }
            return componts;
        }

        public static void RegistCompont(this WebApplicationBuilder builder)
        {

            builder.RegistLog();

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            builder.Services.AddHttpContextAccessor();



            GetComponts()?.ForEach(compont =>
            {
                compont?.Regist(builder);
            });

            builder.Host.ConfigureContainer<ContainerBuilder>((_, containerBuilder) =>
            {
                GetComponts()?.ForEach(compont =>
                {
                    var res = compont?.Regist(containerBuilder);
                    if (res == true)
                    {
                        XjjXmmLoggerHelper.GetLogger().Debug($"注入组件: {compont?.GetType().Name} => {compont?.Order}");
                    }
                });

              //  SqlStartUp.AddSql(containerBuilder);
            });
        }

        //public static void RegistCompont(this WebApplicationBuilder builder, Action<ContainerBuilder> configureDelegate)
        //{
        //    builder.Host.ConfigureContainer<ContainerBuilder>((_, containerBuilder) =>
        //    {
        //        containerBuilder
        //            .AddOther(configureDelegate);
        //    });
        //}

        public static WebApplication UseCompont(this WebApplication app)
        {
            GetComponts()?.ForEach(compont =>
            {
                var res = compont?.Use(app);
                if(res == true)
                {
                    XjjXmmLoggerHelper.GetLogger().Debug($"启用组件: {compont?.GetType().Name} => {compont?.Order}");
                }
            });

            IocManager.Instance.Container = app.Services.GetAutofacRoot();

            return app;
        }

        public static void RegistType(this WebApplicationBuilder builder, Type type)
        {
            builder.Host.ConfigureContainer<ContainerBuilder>((_, builder2) =>
            {
                builder2.RegisterAssemblyTypes(ReflectKit.GetAssembly(type))
                    .Where(a => a.Name.EndsWith("Repository"))
                    .AsImplementedInterfaces()
                    .SingleInstance();

                builder2.RegisterAssemblyTypes(ReflectKit.GetAssembly(type))
                    .Where(a => a.Name.EndsWith("Service"))
                    .AsSelf()
                    .InstancePerLifetimeScope()
                    .EnableClassInterceptors()
                    .InterceptedBy(typeof(LoggerInterceptor))
                    .SingleInstance();
            });
        }
    }
}
